#include "codeports.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <wand/MagickWand.h>

void
SCR_SetPaletteRGB(void)
{
	// [rrgggbbb];
	unsigned char pal[3][256];
	int c;
	for(c = 0; c < 256; c++)
	{
		pal[0][c] = ((c & 0xC0) >> 6) << 4;
		pal[1][c] = ((c & 0x38) >> 3) << 3;
		pal[2][c] = (c & 0x07) << 3;
	}
	SCR_SetPalette(pal);
}

void
SCR_SetBoxColor(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char c;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelColor(box, i, j, &c);
			SCR_SetPixelColor(x + i, y + j, c);
		}
	}
}

void
SCR_SetBoxRGB8(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char r, g, b;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelRGB8(box, i, j, &r, &g, &b);
			SCR_SetPixelRGB8(x + i, y + j, r, g, b);
		}
	}
}

void
SCR_SetBoxRGB16(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char r, g, b;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelRGB16(box, i, j, &r, &g, &b);
			SCR_SetPixelRGB16(x + i, y + j, r, g, b);
		}
	}
}

void
SCR_SetBoxRGB24(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char r, g, b;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelRGB24(box, i, j, &r, &g, &b);
			SCR_SetPixelRGB24(x + i, y + j, r, g, b);
		}
	}
}

void
SCR_SetBoxRGB32(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char r, g, b;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelRGB32(box, i, j, &r, &g, &b);
			SCR_SetPixelRGB32(x + i, y + j, r, g, b);
		}
	}
}

void
SCR_SetBoxRGBA(int x, int y, BOX *box)
{
	unsigned int i, j;
	unsigned char r, g, b, a;
	for(j = 0; j < box->info.height; j++)
	{
		for(i = 0; i < box->info.width; i++)
		{
			BOX_GetPixelRGBA(box, i, j, &r, &g, &b, &a);
			SCR_SetPixelRGBA(x + i, y + j, r, g, b, a);
		}
	}
}

void
SCR_SetImage(char *image)
{
	MagickWand *mw;
	unsigned char *buffer;
	int w, h, d, i, j;
	SCR_GetSize(&w, &h);
	SCR_GetDepth(&d);
	buffer = malloc(w * h * 4);
	mw = NewMagickWand();
	MagickReadImage(mw, image);
	if(w != MagickGetImageWidth(mw) || h != MagickGetImageHeight(mw))
		MagickScaleImage(mw, w, h);
	MagickExportImagePixels(mw, 0, 0, w, h, "RGBA", CharPixel, buffer);
	DestroyMagickWand(mw);
	for(j = 0; j < h; j++)
	{
		for(i = 0; i < w; i++)
		{
			switch(d)
			{
				case 1:
				{
					SCR_SetPixelRGB8(i, j, buffer[(j * w + i) * 4 + 0], buffer[(j * w + i) * 4 + 1] , buffer[(j * w + i) * 4 + 2]);
					break;
				}
				case 2:
				{
					SCR_SetPixelRGB16(i, j, buffer[(j * w + i) * 4 + 0], buffer[(j * w + i) * 4 + 1] , buffer[(j * w + i) * 4 + 2]);
					break;
				}
				case 3:
				{
					SCR_SetPixelRGB24(i, j, buffer[(j * w + i) * 4 + 0], buffer[(j * w + i) * 4 + 1] , buffer[(j * w + i) * 4 + 2]);
					break;
				}
				case 4:
				{
					SCR_SetPixelRGBA(i, j, buffer[(j * w + i) * 4 + 0], buffer[(j * w + i) * 4 + 1] , buffer[(j * w + i) * 4 + 2], buffer[(j * w + i) * 4 + 3]);
					break;
				}
			}
		}
	}
	free(buffer);
}

void
SCR_GetImage(char *image)
{
	MagickWand *mw;
	unsigned char *buffer, r, g, b, a;
	int w, h, d, i, j;
	SCR_GetSize(&w, &h);
	SCR_GetDepth(&d);
	buffer = malloc(w * h * 4);
	for(j = 0; j < h; j++)
	{
		for(i = 0; i < w; i++)
		{
			switch(d)
			{
				case 1:
				{
					SCR_GetPixelRGB8(i, j, &r, &g, &b);
					buffer[(j * w + i) * 4 + 0] = r;
					buffer[(j * w + i) * 4 + 1] = g;
					buffer[(j * w + i) * 4 + 2] = b;
					buffer[(j * w + i) * 4 + 3] = 0;
					break;
				}
				case 2:
				{
					SCR_GetPixelRGB16(i, j, &r, &g, &b);
					buffer[(j * w + i) * 4 + 0] = r;
					buffer[(j * w + i) * 4 + 1] = g;
					buffer[(j * w + i) * 4 + 2] = b;
					buffer[(j * w + i) * 4 + 3] = 0;
					break;
				}
				case 3:
				{
					SCR_GetPixelRGB24(i, j, &r, &g, &b);
					buffer[(j * w + i) * 4 + 0] = r;
					buffer[(j * w + i) * 4 + 1] = g;
					buffer[(j * w + i) * 4 + 2] = b;
					buffer[(j * w + i) * 4 + 3] = 0;
					break;
				}
				case 4:
				{
					SCR_GetPixelRGBA(i, j, &r, &g, &b, &a);
					buffer[(j * w + i) * 4 + 0] = r;
					buffer[(j * w + i) * 4 + 1] = g;
					buffer[(j * w + i) * 4 + 2] = b;
					buffer[(j * w + i) * 4 + 3] = a;
					break;
				}
			}
		}
	}
	mw = NewMagickWand();
	MagickConstituteImage(mw, w, h, "RGBO", CharPixel, buffer);
	free(buffer);
	MagickWriteImage(mw, image);
	DestroyMagickWand(mw);
}
